from django.db import transaction
from rest_framework import serializers

from goods.models import SKUImage, SKU, SKUSpecification, SPU, SpecificationOption


class SKUImageSerializer(serializers.ModelSerializer):
    """图片序列化器类"""
    sku_id = serializers.IntegerField(label='SKU商品id')
    # 关联对象的嵌套序列化,将SKU嵌套序列化为SKU模型类__str__方法的返回值
    sku = serializers.StringRelatedField(label='SKU商品')

    class Meta:
        model = SKUImage
        exclude = ('create_time','update_time')

    def validate_sku_id(self, value):
        # 校验SKU_id对应sku商品是否存在
        try:
            SKU.objects.get(id=value)
        except SKU.DoesNotExist:
            raise serializers.ValidationError("商品不存在")
        return value

    # ModelSerializer 中的create 新增图片:SKUImage.objects.create
    # 但是不会设置默认图片,所以要重写
    def create(self, validated_data):
        # 1.保存图片数据
        # 调用ModelSerializer 中的create
        sku_image = super().create(validated_data)
        # 2.判断设置默认图片
        sku = sku_image.sku
        if not sku.default_image:
            sku.default_image= sku_image.image
            sku.save()
        return sku_image

class SKUSimpleSerializer(serializers.ModelSerializer):
    """商品序列化器类"""
    class Meta:
        model = SKU
        fields = ('id','name')



class SKUSpecSerializer(serializers.ModelSerializer):
    spec_id = serializers.IntegerField(label='规格id')
    option_id = serializers.IntegerField(label='选项id')

    class Meta:
        model = SKUSpecification
        fields = ('spec_id','option_id')

class SKUSerializer(serializers.ModelSerializer):
    """sku序列化器类"""

    # 注意:SKU模型中没有
    spu_id = serializers.IntegerField(label='SPU ID')
    # category 默认序列化为主键
    category = serializers.StringRelatedField(label='第三级分类')
    #
    specs = SKUSpecSerializer(label='SKU具体规格', many=True)

    class Meta:
        model = SKU

        exclude = ('spu','default_image','comments','create_time', 'update_time')

        extra_kwargs = {
            'sales':{
                'read_only':True
            }
        }

    def validate(self, attrs):
        # 获取spu_id
        spu_id = attrs.get('spu_id')
        # 检查spu商品是否存在
        try:
            spu = SPU.objects.get(id=spu_id)

        except SPU.DoesNotExist:
            raise serializers.ValidationError('SPU商品不存在')

        # 获取第三级分类id
        attrs['category_id'] = spu.category3_id

        # 2.1 规格数量
        specs = attrs.get('specs')  #list  几个元素几个规格
        spu_specs = spu.specs.all() # queryset

        spu_spec_count = spu_specs.count()

        if len(specs) != spu_spec_count:
            raise serializers.ValidationError('SPU规格数据有误')

        # 2.2 校验传递数据格式是否合法
        spec_ids = [spec.get('spec_id') for spec in specs]
        spu_spec_ids = [spec.id for spec in spu_specs]

        # 排序
        spec_ids.sort()
        spu_spec_ids.sort()

        if spec_ids != spu_spec_ids:
            raise serializers.ValidationError('SPU规格数据有误')

        # 3.传的选项数据
        for spec in specs:
            # 获取传递的规格/选项id
            spec_id = spec.get('spec_id')
            option_id = spec.get('option_id')

            options = SpecificationOption.objects.filter(spec_id=spec_id)
            option_ids = [option.id for option in options]

            if option_id not in option_ids:
                raise serializers.ValidationError('规格选项数据有误')

        return attrs

    def create(self, validated_data):
        """保存商品数据"""
        specs = validated_data.pop('specs')

        with transaction.atomic():
            # 1.新增sku商品
            sku = SKU.objects.create(**validated_data)

            # 2.保存商品规格信息
            for spec in specs:
                # 获取spec_id option_id
                spec_id = spec.get('spec_id')
                option_id = spec.get('option_id')

                SKUSpecification.objects.create(sku_id=sku.id,
                                                spec_id=spec_id,
                                                option_id=option_id)

        return sku
